package com.ruoyi.course.service.impl;

import com.ruoyi.course.domain.CourseLesson;
import com.ruoyi.course.domain.CourseSchedule;
import com.ruoyi.course.dto.CourseScheduleQueryDto;
import com.ruoyi.course.mapper.CourseLessonMapper;
import com.ruoyi.course.mapper.CourseScheduleMapper;
import com.ruoyi.course.service.ICourseLessonService;
import com.ruoyi.course.vo.CalendarEventVo;
import com.ruoyi.course.vo.CourseScheduleVo;
import com.ruoyi.course.vo.SelectOptionVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 课表Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-06-12
 */
@Service
public class CourseLessonServiceImpl implements ICourseLessonService 
{
    @Autowired
    private CourseLessonMapper courseLessonMapper;
    
    @Autowired
    private CourseScheduleMapper courseScheduleMapper;

    /**
     * 查询课表
     * 
     * @param lessonId 课表主键
     * @return 课表
     */
    @Override
    public CourseLesson selectCourseLessonByLessonId(Integer lessonId)
    {
        return courseLessonMapper.selectCourseLessonByLessonId(lessonId);
    }

    /**
     * 查询课表列表
     * 
     * @param courseLesson 课表
     * @return 课表
     */
    @Override
    public List<CourseLesson> selectCourseLessonList(CourseLesson courseLesson)
    {
        return courseLessonMapper.selectCourseLessonList(courseLesson);
    }

    /**
     * 新增课表
     * 
     * @param courseLesson 课表
     * @return 结果
     */
    @Override
    public int insertCourseLesson(CourseLesson courseLesson)
    {
        return courseLessonMapper.insertCourseLesson(courseLesson);
    }

    /**
     * 修改课表
     * 
     * @param courseLesson 课表
     * @return 结果
     */
    @Override
    public int updateCourseLesson(CourseLesson courseLesson)
    {
        return courseLessonMapper.updateCourseLesson(courseLesson);
    }

    /**
     * 批量删除课表
     * 
     * @param lessonIds 需要删除的课表主键
     * @return 结果
     */
    @Override
    public int deleteCourseLessonByLessonIds(Integer[] lessonIds)
    {
        return courseLessonMapper.deleteCourseLessonByLessonIds(lessonIds);
    }

    /**
     * 删除课表信息
     * 
     * @param lessonId 课表主键
     * @return 结果
     */
    @Override
    public int deleteCourseLessonByLessonId(Integer lessonId)
    {
        return courseLessonMapper.deleteCourseLessonByLessonId(lessonId);
    }

    /**
     * 获取校区选项列表
     * 
     * @return 校区选项列表
     */
    @Override
    public List<SelectOptionVo> getCampusOptions()
    {
        return courseLessonMapper.getCampusOptions();
    }

    /**
     * 根据校区id获取班级选项列表
     * 
     * @param campusId 校区id
     * @return 班级选项列表
     */
    @Override
    public List<SelectOptionVo> getClassOptionsByCampusId(Integer campusId)
    {
        return courseLessonMapper.getClassOptionsByCampusId(campusId);
    }

    /**
     * 获取课程表日历数据
     * 
     * @param queryDto 查询条件
     * @return 课程表日历数据
     */
    @Override
    public CourseScheduleVo getCourseScheduleCalendar(CourseScheduleQueryDto queryDto)
    {
        // 根据班级id查询课程表和班级信息
        CourseScheduleVo scheduleVo = courseLessonMapper.getCourseScheduleInfo(queryDto.getClaId());
        
        if (scheduleVo != null) {
            // 从数据库读取真实的课程安排数据
            List<CalendarEventVo> events = generateEventsFromDatabase(queryDto.getClaId(), scheduleVo);
            scheduleVo.setEvents(events);
        }
        
        return scheduleVo;
    }

    /**
     * 从数据库读取课程安排数据生成日历事件
     * 
     * @param claId 班级ID
     * @param scheduleVo 课程表信息
     * @return 日历事件列表
     */
    private List<CalendarEventVo> generateEventsFromDatabase(Integer claId, CourseScheduleVo scheduleVo)
    {
        List<CalendarEventVo> events = new ArrayList<>();
        
        // 从数据库查询有效的课程安排（状态为1的记录）
        List<CourseSchedule> courseSchedules = courseScheduleMapper.selectCourseScheduleByClaId(claId.longValue());
        
        if (courseSchedules != null && !courseSchedules.isEmpty()) {
            // 为每个课程安排创建日历事件
            for (CourseSchedule schedule : courseSchedules) {
                // 只处理状态为1（正常）的课程安排
                if ("1".equals(schedule.getStatus()) && schedule.getSpecificDate() != null) {
                    // 解析specificDate字段，支持单日期和日期范围
                    List<LocalDate> courseDates = parseSpecificDate(schedule.getSpecificDate());
                    
                    // 为每个日期创建事件
                    for (LocalDate date : courseDates) {
                        CalendarEventVo event = createEventFromSchedule(schedule, date, scheduleVo.getCourseName());
                        if (event != null) {
                            events.add(event);
                        }
                    }
                }
            }
        }
        
        return events;
    }
    
    /**
     * 解析specificDate字段，支持单日期和日期范围
     * 支持格式：
     * - 单日期：2025-06-18
     * - 日期范围：2025-06-18~2025-06-20
     * 
     * @param specificDate 具体日期字符串
     * @return 日期列表
     */
    private List<LocalDate> parseSpecificDate(String specificDate) {
        List<LocalDate> dates = new ArrayList<>();
        
        if (specificDate == null || specificDate.trim().isEmpty()) {
            return dates;
        }
        
        specificDate = specificDate.trim();
        
        try {
            if (specificDate.contains("~")) {
                // 日期范围格式：2025-06-18~2025-06-20
                String[] dateRange = specificDate.split("~");
                if (dateRange.length == 2) {
                    LocalDate startDate = LocalDate.parse(dateRange[0].trim());
                    LocalDate endDate = LocalDate.parse(dateRange[1].trim());
                    
                    // 生成范围内的所有日期
                    LocalDate current = startDate;
                    while (!current.isAfter(endDate)) {
                        dates.add(current);
                        current = current.plusDays(1);
                    }
                }
            } else {
                // 单日期格式：2025-06-18
                LocalDate singleDate = LocalDate.parse(specificDate);
                dates.add(singleDate);
            }
        } catch (Exception e) {
            // 如果解析失败，记录错误但不中断处理
            System.err.println("解析日期失败: " + specificDate + ", 错误: " + e.getMessage());
        }
        
        return dates;
    }
    
    /**
     * 解析日期字符串
     * 支持格式：yyyy-MM-dd
     */
    private LocalDate parseDate(String dateStr) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return null;
        }
        
        try {
            return LocalDate.parse(dateStr.trim());
        } catch (Exception e) {
            // 如果解析失败，返回null
            return null;
        }
    }
    

    
    /**
     * 根据课程安排创建日历事件
     */
    private CalendarEventVo createEventFromSchedule(CourseSchedule schedule, LocalDate date, String courseName) {
        try {
            CalendarEventVo event = new CalendarEventVo();
            event.setId(schedule.getScheduleId().toString());
            event.setTitle(courseName + " - " + schedule.getTimePeriod());
            
            // 解析时间段并设置开始结束时间
            String[] timeInfo = parseTimePeriod(schedule.getTimePeriod());
            event.setStart(date.toString() + "T" + timeInfo[0]);
            event.setEnd(date.toString() + "T" + timeInfo[1]);
            event.setAllDay(false);
            
            // 根据课程类型设置不同颜色
            String[] colors = getColorByScheduleType(schedule.getScheduleType());
            event.setBackgroundColor(colors[0]);
            event.setBorderColor(colors[1]);
            
            // 设置扩展属性
            Map<String, Object> extendedProps = new HashMap<>();
            extendedProps.put("scheduleId", schedule.getScheduleId());
            extendedProps.put("scheduleType", schedule.getScheduleType());
            event.setExtendedProps(extendedProps);
            
            return event;
        } catch (Exception e) {
            // 如果解析失败，返回null
            return null;
        }
    }
    
    /**
     * 解析时间段
     * 支持格式：7:30-11:00、09:00-11:30、14:00-16:00等
     * 只支持整点（如9:00）或半点（如9:30）的时间
     */
    private String[] parseTimePeriod(String timePeriod) {
        if (timePeriod == null || timePeriod.trim().isEmpty()) {
            return new String[]{"09:00:00", "11:00:00"};
        }
        
        timePeriod = timePeriod.trim();
        
        // 匹配时间格式：支持 H:MM-H:MM 或 HH:MM-HH:MM 格式
        // 例如：7:30-11:00, 09:00-11:30, 14:00-16:00
        if (timePeriod.matches("\\d{1,2}:(00|30)-\\d{1,2}:(00|30)")) {
            String[] times = timePeriod.split("-");
            String startTime = formatTime(times[0]);
            String endTime = formatTime(times[1]);
            return new String[]{startTime, endTime};
        }
        
        // 如果格式不匹配，返回默认时间
        return new String[]{"09:00:00", "11:00:00"};
    }
    
    /**
     * 格式化时间，确保时间格式为HH:MM:SS
     * 
     * @param time 时间字符串，如"7:30"或"09:00"
     * @return 格式化后的时间字符串，如"07:30:00"或"09:00:00"
     */
    private String formatTime(String time) {
        if (time == null || time.trim().isEmpty()) {
            return "09:00:00";
        }
        
        time = time.trim();
        String[] parts = time.split(":");
        
        if (parts.length == 2) {
            // 补齐小时位数（如果是单位数）
            String hour = parts[0].length() == 1 ? "0" + parts[0] : parts[0];
            String minute = parts[1];
            
            // 验证分钟只能是00或30
            if (!"00".equals(minute) && !"30".equals(minute)) {
                minute = "00"; // 如果不是00或30，默认设为00
            }
            
            return hour + ":" + minute + ":00";
        }
        
        return "09:00:00";
    }
    
    /**
     * 根据课程类型获取颜色
     * 1-一键添加：蓝色
     * 2-手动添加：绿色  
     * 3-补课：橙色
     * 4-特殊课程：紫色
     */
    private String[] getColorByScheduleType(String scheduleType) {
        if (scheduleType == null) {
            return new String[]{"#409EFF", "#409EFF"}; // 默认蓝色
        }
        
        switch (scheduleType) {
            case "1": // 一键添加
                return new String[]{"#409EFF", "#409EFF"}; // 蓝色
            case "2": // 手动添加
                return new String[]{"#67C23A", "#67C23A"}; // 绿色
            case "3": // 补课
                return new String[]{"#E6A23C", "#E6A23C"}; // 橙色
            case "4": // 特殊课程
                return new String[]{"#9C27B0", "#9C27B0"}; // 紫色
            default:
                return new String[]{"#409EFF", "#409EFF"}; // 默认蓝色
        }
    }
    
    /**
     * 根据时间段获取颜色（备用方法）
     * 根据开始时间判断是上午、下午还是晚上
     */
    private String[] getColorByTimePeriod(String timePeriod) {
        if (timePeriod == null || timePeriod.trim().isEmpty()) {
            return new String[]{"#409EFF", "#409EFF"};
        }
        
        // 解析开始时间来判断时间段
        String[] timeInfo = parseTimePeriod(timePeriod);
        String startTime = timeInfo[0];
        
        try {
            // 提取小时数
            int hour = Integer.parseInt(startTime.split(":")[0]);
            
            if (hour >= 6 && hour < 12) {
                // 上午 6:00-11:59
                return new String[]{"#409EFF", "#409EFF"}; // 蓝色
            } else if (hour >= 12 && hour < 18) {
                // 下午 12:00-17:59
                return new String[]{"#67C23A", "#67C23A"}; // 绿色
            } else if (hour >= 18 && hour <= 23) {
                // 晚上 18:00-23:59
                return new String[]{"#E6A23C", "#E6A23C"}; // 橙色
            } else {
                // 深夜或凌晨 0:00-5:59
                return new String[]{"#909399", "#909399"}; // 灰色
            }
        } catch (Exception e) {
            // 解析失败，返回默认颜色
            return new String[]{"#409EFF", "#409EFF"};
        }
    }
}
